#include <malloc.h>
#include <string.h>
#include "symtable.h"

//作用是建立新的链表，如果内存不够就返回NULL pointer，否则返回结构体指针
struct Link* LinkTable_new(void)
{
    struct Link* newLink = malloc(sizeof(struct Link));
    if(newLink != NULL)
    {
	newLink->Next = NULL;
	newLink->Key = NULL;
    }
    return newLink;

}

//作用是释放链表由指针oLink指向的，链表所占用的内存。包括所以已经分配的结构体
void LinkTable_free(struct Link* oLink)
{
    struct Link* tmp = NULL;
    while(oLink != NULL)
    {
	tmp = oLink->Next;
	free(oLink);
	oLink = NULL;
	oLink = tmp;
    }
}

//返回链表中节点的个数
int LinkTable_getLength(struct Link* oLink)
{
    int result = 0;
    if(oLink != NULL)
    {
	struct Link* node = oLink;
	while(node != NULL)
	{
	    result++;
	    node = node->Next;
	}
    }
    return result;
}

//如果在链表中不存在pcKey，则将pcKey和pvValue插入链表并返回1
//如果没有内存空间或pvKey已经存在于链表之中则返回0
int Link_put(struct Link* oLink, 
	     const char* pcKey, 
	     const void* pvValue)
{
    char* mystrcpy(const char*);
    int result = 0;
    if(oLink->Key == NULL)
    {
	oLink->Key = mystrcpy(pcKey);
	oLink->Value = (void*)pvValue;
	result = 1;
    }
    else
    {
	struct Link* node = oLink;
        while(node->Next != NULL)
	{
	    if(strcmp(node->Key,pcKey) == 0)
	    {
		return result;
	    }
	    node = node->Next;
	}
	struct Link* newLink = (struct Link*)malloc(sizeof(struct Link));
	newLink->Key = mystrcpy(pcKey);
	newLink->Value = (void*)pvValue;
	if(newLink == NULL)
	{
	    return result;
	}
	node->Next = newLink;
	newLink->Next = NULL;
	result = 1;
    }
    return result;   
}

//在链表中查找pcKey，如果找到则将其对应的旧值替换为pvValue并返回指向旧值的指针。
//如果找不到则返回NULL pointer
void* Link_replace(struct Link* oLink, 
		   const char* pcKey, 
		   const void* pvValue)
{
    char* mystrcpy(const char*);
    struct Link* node = oLink;
    struct Link* result = NULL;
    while(node != NULL)
    {
	if(strcmp(node->Key,pcKey) == 0)
	{
	    result = node;
	    node->Key = mystrcpy(pcKey);
	    node->Value = (void*)pvValue;
	    break;
	}
	node = node->Next;
    }
    return result;
}

//在链表中查找pcKey，如果找到则返回1，否则返回0.该操作不对链表做任何修改
int Link_constains(struct Link* oLink, 
		   const char* pcKey)
{
    int result = 0;
    struct Link* node = oLink;
    while(node != NULL)
    {
	if(strcmp(node->Key,pcKey) == 0)
	{
	    result = 1;
	    break;
	}
	node = node->Next;
    }
    return result;
}

//在链表中查找pcKey，如果找到则返回其对应的值，否则返回NULL pointer。
//该操作不对链表做任何修改
void* Link_get(struct Link* oLink, 
	       const char* pcKey)
{
    void* result = NULL;
    struct Link* node = oLink;
    while(node != NULL)
    {
	if(strcmp(node->Key,pcKey) == 0)
	{
	    result = node->Value;
	    break;
	}
	node = node->Next;
    }
    return result;
}

//在链表中查找pcKey，如果找到则删除pcKey和对应的值，并返回指向旧值的指针。
//否则返回NULL pointer
void* Link_remove(struct Link* oLink, 
		  const char* pcKey)
{
    void* result = NULL;
    struct Link* node = oLink;
    if(strcmp(node->Key,pcKey) == 0)
    {
	oLink = node->Next;
	result = (void*)node;
    }
    else
    {
	while(node != NULL)
	{
	    if(strcmp(node->Next->Key,pcKey) == 0)
	    {
		result = (void*)node->Next;
		node->Next = node->Next->Next;
		break;
	    }
	}
    }
    return result;
}

char* mystrcpy(const char* str)
{
    char* result = NULL;
    int len = strlen(str);
    result = (char*)malloc(sizeof(char) * (len + 1));
    strcpy(result, str);
    return result;
}
